<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
<meta name="viewport"
      content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">

    <meta name="author" content="Tommas">


    <meta name="subtitle" content="Tommas Blog">


    <meta name="description" content="Keep quiet time for time">



<title>YAML脚本学习笔记 | Tommas&#39;s Blog</title>



    <link rel="icon" href="/images/favicon-32x32-next.png">




    <!-- stylesheets list from _config.yml -->
    
    <link rel="stylesheet" href="/css/style.css">
    



    <!-- scripts list from _config.yml -->
    
    <script src="/js/script.js"></script>
    
    <script src="/js/tocbot.min.js"></script>
    



    
    
        
    


<meta name="generator" content="Hexo 7.2.0"></head>

<body>
    <script>
        // this function is used to check current theme before page loaded.
        (() => {
            const currentTheme = window.localStorage && window.localStorage.getItem('theme') || '';
            const isDark = currentTheme === 'dark';
            const pagebody = document.getElementsByTagName('body')[0]
            if (isDark) {
                pagebody.classList.add('dark-theme');
                // mobile
                document.getElementById("mobile-toggle-theme").innerText = "· Dark"
            } else {
                pagebody.classList.remove('dark-theme');
                // mobile
                document.getElementById("mobile-toggle-theme").innerText = "· Light"
            }
        })();
    </script>

    <div class="wrapper">
        <header>
    <nav class="navbar">
        <div class="container">
            <div class="navbar-header header-logo"><a href="/">Tommas&#39;s Blog</a></div>
            <div class="menu navbar-right">
                
                    <a class="menu-item" href="/archives">Posts</a>
                
                    <a class="menu-item" href="/category">Categories</a>
                
                    <a class="menu-item" href="/tag">Tags</a>
                
                    <a class="menu-item" href="/about">About</a>
                
                <input id="switch_default" type="checkbox" class="switch_default">
                <label for="switch_default" class="toggleBtn"></label>
            </div>
        </div>
    </nav>

    
    <nav class="navbar-mobile" id="nav-mobile">
        <div class="container">
            <div class="navbar-header">
                <div>
                    <a href="/">Tommas&#39;s Blog</a><a id="mobile-toggle-theme">·&nbsp;Light</a>
                </div>
                <div class="menu-toggle" onclick="mobileBtn()">&#9776; Menu</div>
            </div>
            <div class="menu" id="mobile-menu">
                
                    <a class="menu-item" href="/archives">Posts</a>
                
                    <a class="menu-item" href="/category">Categories</a>
                
                    <a class="menu-item" href="/tag">Tags</a>
                
                    <a class="menu-item" href="/about">About</a>
                
            </div>
        </div>
    </nav>

</header>
<script>
    var mobileBtn = function f() {
        var toggleMenu = document.getElementsByClassName("menu-toggle")[0];
        var mobileMenu = document.getElementById("mobile-menu");
        if(toggleMenu.classList.contains("active")){
           toggleMenu.classList.remove("active")
            mobileMenu.classList.remove("active")
        }else{
            toggleMenu.classList.add("active")
            mobileMenu.classList.add("active")
        }
    }
</script>
            <div class="main">
                <div class="container">
    
    
        <div class="post-toc">
    <div class="tocbot-list">
    </div>
    <div class="tocbot-list-menu">
        <a class="tocbot-toc-expand" onclick="expand_toc()">Expand all</a>
        <a onclick="go_top()">Back to top</a>
        <a onclick="go_bottom()">Go to bottom</a>
    </div>
</div>

<script>
    var tocbot_timer;
    var DEPTH_MAX = 6; // 为 6 时展开所有
    var tocbot_default_config = {
        tocSelector: '.tocbot-list',
        contentSelector: '.post-content',
        headingSelector: 'h1, h2, h3, h4, h5',
        orderedList: false,
        scrollSmooth: true,
        onClick: extend_click,
    };

    function extend_click() {
        clearTimeout(tocbot_timer);
        tocbot_timer = setTimeout(function() {
            tocbot.refresh(obj_merge(tocbot_default_config, {
                hasInnerContainers: true
            }));
        }, 420); // 这个值是由 tocbot 源码里定义的 scrollSmoothDuration 得来的
    }

    document.ready(function() {
        tocbot.init(obj_merge(tocbot_default_config, {
            collapseDepth: 1
        }));
    });

    function expand_toc() {
        var b = document.querySelector('.tocbot-toc-expand');
        var expanded = b.getAttribute('data-expanded');
        expanded ? b.removeAttribute('data-expanded') : b.setAttribute('data-expanded', true);
        tocbot.refresh(obj_merge(tocbot_default_config, {
            collapseDepth: expanded ? 1 : DEPTH_MAX
        }));
        b.innerText = expanded ? 'Expand all' : 'Collapse all';
    }

    function go_top() {
        window.scrollTo(0, 0);
    }

    function go_bottom() {
        window.scrollTo(0, document.body.scrollHeight);
    }

    function obj_merge(target, source) {
        for (var item in source) {
            if (source.hasOwnProperty(item)) {
                target[item] = source[item];
            }
        }
        return target;
    }
</script>
    

    
    <article class="post-wrap">
        <header class="post-header">
            <h1 class="post-title">YAML脚本学习笔记</h1>
            
                <div class="post-meta">
                    
                        Author: <a itemprop="author" rel="author" href="/">Tommas</a>
                    

                    
                        <span class="post-time">
                        Date: <a href="#">December 3, 2017&nbsp;&nbsp;12:34:36</a>
                        </span>
                    
                    
                        <span class="post-category">
                    Category:
                            
                                <a href="/categories/xml/">xml</a>
                            
                        </span>
                    
                </div>
            
        </header>

        <div class="post-content">
            <p><img src="https://s2.loli.net/2023/04/16/pWn3RYiD86aGONA.png"></p>
<p>YAML是“另一种标记语言”的外语缩写；但为了强调这种语言以数据做为中心，而不是以置标语言为重点，而用返璞词重新命名。它是一种直观的能够被电脑识别的数据序列化格式，是一个可读性高并且容易被人类阅读，容易和脚本语言交互，用来表达资料序列的编程语言。<br>它是类似于标准通用标记语言的子集XML的数据描述语言，语法比XML简单很多。</p>
<span id="more"></span>
<p>诞生<br>YAML参考了其他多种语言，包括：XML、C语言、Python、Perl以及电子邮件格式RFC2822。<br>Clark Evans在2001年5月在首次发表了这种语言，另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者。<br>命名<br>YAML是”YAML Ain’t a Markup Language”（YAML不是一种置标语言）的递归缩写。<br>在开发的这种语言时，YAML 的意思其实是：”Yet Another Markup Language”（仍是一种置标语言），<br>功能<br>YAML的语法和其他高阶语言类似，并且可以简单表达清单、散列表，标量等资料形态、。<br>它使用空白符号缩排和大量依赖外观的特色，特别适合用来表达或编辑数据结构、各种设定档、倾印除错内容、文件大纲（例如：许多电子邮件标题格式和YAML非常接近）。<br>尽管它比较适合用来表达阶层式（hierarchical model）的数据结构，不过也有精致的语法可以表示关联性（relational model）的资料。<br>由于YAML使用空白字符和分行来分隔资料，使的他特别适合用grep、Python、Perl、Ruby操作。<br>其让人最容易上手的特色是巧妙避开各种封闭符号，如：引号、各种括号等，这些符号在嵌套结构中会变得复杂而难以辨认。</p>
<h1 id="YAML预研文档"><a href="#YAML预研文档" class="headerlink" title="YAML预研文档"></a>YAML预研文档</h1><h2 id="YAML概要"><a href="#YAML概要" class="headerlink" title="YAML概要"></a>YAML概要</h2><p><a target="_blank" rel="noopener" href="http://yaml.org/">YAML</a>是”YAML Ain’t a Markup Language”（YAML不是一种置标语言）的递归缩写，早先YAML的意思其实是：”Yet Another Markup Language”（另外一种置标语言），但为了强调这种语言以数据做为中心，而不是以置标语言为重点，而用返璞词重新命名，YAML的官方定义很简单，即<strong>一种人性化的数据格式定义语言</strong>，其主要功能用途类似于XML或JSON，YAML使用空白字符和分行来分隔数据，且巧妙避开各种封闭符号，如：引号、括号等，以避免这些符号在复杂层次结构中变得难以辨认。YAML的语法与高阶语言类似，可以很简单地表述<em>序列（java中的list）、杂凑表（java中的map）、标量（java中的基本类型等）</em>数据结构，它重点强调可阅读性。</p>
<h2 id="YAML-vs-XML"><a href="#YAML-vs-XML" class="headerlink" title="YAML vs XML"></a>YAML vs XML</h2><p>与YAML相似的数据格式定义语言是XML，YAML比XML优越性表现在</p>
<blockquote>
<p><strong>优势:</strong></p>
</blockquote>
<blockquote>
<ul>
<li>YAML的可读性好</li>
<li>YAML和脚本语言的交互性好</li>
<li>YAML使用实现语言的数据类型</li>
<li>YAML有一个一致的信息模型</li>
<li>YAML易于实现</li>
</ul>
</blockquote>
<p>上面5条是XML不足的地方，同时，YAML也具有XML的下列优点：</p>
<blockquote>
<ul>
<li>YAML可以基于流来处理</li>
<li>YAML表达能力强，扩展性好</li>
</ul>
</blockquote>
<p>YAML类似于XML的数据描述语言，语法比XML简单很多，YAML试图用一种比XML更敏捷的方式，来完成XML所完成的任务。</p>
<hr>
<h2 id="YAML-vs-JSON"><a href="#YAML-vs-JSON" class="headerlink" title="YAML vs JSON"></a>YAML vs JSON</h2><p>JSON的语法其实是YAML的子集，大部分的JSON文件都可以被YAML的剖析器剖析。虽然大部分的数据分层形式也可以使用类似JSON的格式，不过YAML并不建议这样使用，除非这样编写能让文件可读性增加，更重要的是，YAML的许多扩展在JSON是找不到的，如：<em>进阶资料形态</em>、<em>关系锚点</em>、<em>字串不需要引号</em>、<em>映射资料形态会储存键值的顺序</em>等。</p>
<h2 id="YAML用途"><a href="#YAML用途" class="headerlink" title="YAML用途"></a>YAML用途</h2><h3 id="脚本语言"><a href="#脚本语言" class="headerlink" title="脚本语言"></a>脚本语言</h3><p>由于实现简单，解析成本很低，YAML特别适合在脚本语言中使用。列一下现有的语言实现：Ruby，Java，Perl，Python，PHP，OCaml，JavaScript，除了Java，其他都是脚本语言。</p>
<h3 id="序列化"><a href="#序列化" class="headerlink" title="序列化"></a>序列化</h3><p>YAML比较适合做序列化。因为它是宿主语言数据类型直转的。</p>
<h3 id="配置文件"><a href="#配置文件" class="headerlink" title="配置文件"></a>配置文件</h3><p>YAML做配置文件也不错。写YAML要比写XML快得多(<strong>无需关注标签或引号</strong>)，并且比ini文档功能更强。</p>
<h3 id="调试"><a href="#调试" class="headerlink" title="调试"></a>调试</h3><p>由于其很强的阅读性，用于调试过程中dump出信息供分析也是一种比较方便的做法。</p>
<h2 id="YAML缺陷与不足"><a href="#YAML缺陷与不足" class="headerlink" title="YAML缺陷与不足"></a>YAML缺陷与不足</h2><p>YAML没有自己的数据类型的定义，而是使用实现语言的数据类型。一个YAML文件，在不同语言中解析后得到的数据类型可能会不同，由于其兼容性问题，不同语言间的数据流转不建议使用YAML。</p>
<h2 id="YAML语法与范例"><a href="#YAML语法与范例" class="headerlink" title="YAML语法与范例"></a>YAML语法与范例</h2><blockquote>
<ul>
<li>YAML使用可打印的Unicode字符，可使用UTF-8或UTF-16</li>
<li>使用<strong>空白字符</strong>（不能使用<kbd>Tab</kbd>）分层，同层元素左侧对齐</li>
<li>单行注解由井字号（<kbd> #</kbd> ）开始，可以出现在行中任何位置</li>
<li>每个清单成员以单行表示，并用短杠+空白（<kbd>-  </kbd>）起始</li>
<li>每个杂凑表的成员用冒号+空白（<kbd>:  </kbd>）分开键和值</li>
<li>杂凑表的键值可以用问号 (<kbd>?</kbd>)起始，表示多个词汇组成的键值</li>
<li>字串一般不使用引号，但必要的时候可以用引号框住</li>
<li>使用双引号表示字串时，可用倒斜线（<kbd>&lt;/kbd>）进行特殊字符转义</li>
<li>区块的字串用缩排和修饰词（非必要）来和其他资料分隔，有新行保留（使用符号<kbd>|</kbd>）或新行折叠（使用符号<kbd>></kbd>）两种方式</li>
<li>在单一档案中，可用连续三个连字号（<kbd>---</kbd>）区分多个档案</li>
<li>可选择性的连续三个点号（<kbd>...</kbd>）用来表示档案结尾(在流式传输时非常有用，不需要关闭流即可知道到达结尾处)</li>
<li>重复的内容可使从参考标记星号 (<kbd>*</kbd>)复制到锚点标记（<kbd>&</kbd>）</li>
<li>指定格式可以使用两个惊叹号 ( !! )，后面接上名称</li>
</ul>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">receipt:     Oz-Ware Purchase Invoice</span><br><span class="line">date:        2007-08-06</span><br><span class="line">customer:</span><br><span class="line">    given:   Dorothy</span><br><span class="line">    family:  Gale</span><br><span class="line">items:</span><br><span class="line">    - part_no:   A4786</span><br><span class="line">      descrip:   Water Bucket (Filled)</span><br><span class="line">      price:     1.47</span><br><span class="line">      quantity:  4</span><br><span class="line">    - part_no:   E1628</span><br><span class="line">      descrip:   High Heeled &quot;Ruby&quot; Slippers </span><br><span class="line">      price:     100.27</span><br><span class="line">      quantity:  1</span><br><span class="line">bill-to:  &amp;id001</span><br><span class="line">    street: | </span><br><span class="line">            123 Tornado Alley</span><br><span class="line">            Suite 16</span><br><span class="line">    city:   East Westville</span><br><span class="line">    state:  KS</span><br><span class="line">ship-to:  *id001   </span><br><span class="line">specialDelivery:  &gt;</span><br><span class="line">    Follow the Yellow Brick</span><br><span class="line">    Road to the Emerald City.</span><br><span class="line">    Pay no attention to the </span><br><span class="line">    man behind the curtain.</span><br><span class="line">...</span><br></pre></td></tr></table></figure>
<p>这个文件的的顶层由七个键值组成：其中一个键值”items”，是个两个元素构成的清单，清单中的两个元素同时也是包含了四个键值的杂凑表。<br>文件中重复的部分处理方式：使用锚点（&amp;）和参考（*）标签将”bill-to”杂凑表的内容复制到”ship-to”杂凑表。也可以在文件中加入选择性的空行，以增加可读性。</p>
<h2 id="YAML的JAVA实现"><a href="#YAML的JAVA实现" class="headerlink" title="YAML的JAVA实现"></a>YAML的JAVA实现</h2><p>YAML已经有了多种语言不少实现，详见<a target="_blank" rel="noopener" href="http://yaml.org/">YAML官网</a>。<br>一般YAML文件扩展名为.yaml，比如John.yaml，其内容为：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">name: John Smith</span><br><span class="line">age: 37</span><br><span class="line">children:</span><br><span class="line">    - name: Jimmy Smith</span><br><span class="line">      age: 15</span><br><span class="line">    - name: Jenny Smith</span><br><span class="line">      age: 12</span><br><span class="line">spouse:</span><br><span class="line">    name: Jane Smith</span><br><span class="line">    age: 25</span><br></pre></td></tr></table></figure>

<blockquote>
<p>由于yaml的超强可读性，我们了解到：John今年37岁，两个孩子Jimmy 和Jenny活泼可爱，妻子Jane年轻美貌，而且年仅25岁，一个幸福的四口之家。<br>对John.yaml进行java描述，抽象出一个Person类，如下：</p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">public class Person &#123;</span><br><span class="line">    private String name;</span><br><span class="line">    private int age;</span><br><span class="line">    private Person sponse;</span><br><span class="line">    private Person[] children;</span><br><span class="line">    // setXXX, getXXX方法略.</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>现在我们使用java装配一个Jone：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">Person john = new Person();</span><br><span class="line">john.setAge(37);</span><br><span class="line">john.setName(&quot;John Smith&quot;);</span><br><span class="line">Person sponse = new Person();</span><br><span class="line">sponse.setName(&quot;Jane Smith&quot;);</span><br><span class="line">sponse.setAge(25);</span><br><span class="line">john.setSponse(sponse);</span><br><span class="line">Person[] children = &#123;new Person(), new Person()&#125;;</span><br><span class="line">children[0].setName(&quot;Jimmy Smith&quot;);</span><br><span class="line">children[0].setAge(15);</span><br><span class="line">children[1].setName(&quot;Jenny Smith&quot;);</span><br><span class="line">children[1].setAge(12);</span><br><span class="line">john.setChildren(children);</span><br></pre></td></tr></table></figure>

<h3 id="使用SnakeYAML实现"><a href="#使用SnakeYAML实现" class="headerlink" title="使用SnakeYAML实现"></a>使用SnakeYAML实现</h3><p>项目主页：<a target="_blank" rel="noopener" href="http://code.google.com/p/snakeyaml/">http://code.google.com/p/snakeyaml/</a><br>使用手册：<a target="_blank" rel="noopener" href="https://code.google.com/p/snakeyaml/wiki/Documentation">https://code.google.com/p/snakeyaml/wiki/Documentation</a><br>SnakeYAML是一个标准的YAML的java实现，它有以下特点：</p>
<blockquote>
<ul>
<li>完全支持YAML 1.1，可以跑通规范中的所有示例</li>
<li>支持YAML的所有类型</li>
<li>支持UTF-8&#x2F;UTF-16的输入和输出</li>
<li>提供了本地java对象的序列化和反序列化的高层API</li>
<li>提供相对合理的错误提示信息</li>
</ul>
</blockquote>
<p>使用SnakeYAML将john dump出来，<strong>如果有引用相同对象，则dump出到yaml文件会自动使用<kbd>&</kbd>和<kbd>*</kbd>进行锚点和引用</strong>：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">DumperOptions options = new DumperOptions();</span><br><span class="line">options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);</span><br><span class="line">Yaml yaml = new Yaml(options);</span><br><span class="line">//Yaml yaml = new Yaml();</span><br><span class="line">String dump = yaml.dump(john);</span><br><span class="line">System.out.println(dump);</span><br></pre></td></tr></table></figure>
<p>内容如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">!!Person</span><br><span class="line">age: 37</span><br><span class="line">children:</span><br><span class="line">- age: 15</span><br><span class="line">  children: null</span><br><span class="line">  name: Jimmy Smith</span><br><span class="line">  sponse: null</span><br><span class="line">- age: 12</span><br><span class="line">  children: null</span><br><span class="line">  name: Jenny Smith</span><br><span class="line">  sponse: null</span><br><span class="line">name: John Smith</span><br><span class="line">sponse:</span><br><span class="line">  age: 25</span><br><span class="line">  children: null</span><br><span class="line">  name: Jane Smith</span><br><span class="line">  sponse: null</span><br></pre></td></tr></table></figure>
<p>现在用SnakeYAML把yaml load进来，<strong>如果yaml文件中使用了<kbd>&</kbd>和<kbd>*</kbd>，则会自动对load出来的对象赋相同的值</strong>：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Yaml yaml = new Yaml();</span><br><span class="line">Object load = yaml.load(new FileInputStream(new File(&quot;jhon.yaml&quot;)));</span><br><span class="line">System.out.println(load.getClass());</span><br><span class="line">System.out.println(yaml.dump(load));</span><br></pre></td></tr></table></figure>
<p>或</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Yaml yaml = new Yaml(options);</span><br><span class="line">Person person = yaml.loadAs(inputStream, Person.class);</span><br><span class="line">System.out.println(person.getSponse().getChildren().length);</span><br></pre></td></tr></table></figure>
<p>如果一个yaml文件中有多个文档，由<kbd>---</kbd>分割，解析如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">Yaml yaml = new Yaml();</span><br><span class="line">        int counter = 0;</span><br><span class="line">        for (Object data : yaml.loadAll(input)) &#123;</span><br><span class="line">            System.out.println(data);</span><br><span class="line">            counter++;</span><br><span class="line">        &#125;</span><br></pre></td></tr></table></figure>
<p>保存一个Map对象：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">Map&lt;String, Object&gt; data = new HashMap&lt;String, Object&gt;();</span><br><span class="line">        data.put(&quot;name&quot;, &quot;Silenthand Olleander&quot;);</span><br><span class="line">        data.put(&quot;race&quot;, &quot;Human&quot;);</span><br><span class="line">        data.put(&quot;traits&quot;, new String[] &#123; &quot;ONE_HAND&quot;, &quot;ONE_EYE&quot; &#125;);</span><br><span class="line">        Yaml yaml = new Yaml();</span><br><span class="line">        String output = yaml.dump(data);</span><br><span class="line">        System.out.println(output);</span><br><span class="line">    // or</span><br><span class="line">    StringWriter writer = new StringWriter();</span><br><span class="line">    yaml.dump(data, writer);</span><br><span class="line">    System.out.println(writer.toString());</span><br></pre></td></tr></table></figure>
<p>将多个文档dump出到同一个yaml文件中去：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">List&lt;Integer&gt; docs = new LinkedList&lt;Integer&gt;();</span><br><span class="line">    for (int i = 1; i &lt; 4; i++) &#123;</span><br><span class="line">        docs.add(i);</span><br><span class="line">    &#125;</span><br><span class="line">    DumperOptions options = new DumperOptions();</span><br><span class="line">    //options.setCanonical(true);</span><br><span class="line">    options.explicitStart(true);</span><br><span class="line">    Yaml yaml = new Yaml(options);</span><br><span class="line">    System.out.println(yaml.dump(docs));</span><br><span class="line">    System.out.println(yaml.dumpAll(docs.iterator()));</span><br></pre></td></tr></table></figure>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">--- [1, 2, 3]</span><br><span class="line"></span><br><span class="line">--- 1</span><br><span class="line">--- 2</span><br><span class="line">--- 3</span><br></pre></td></tr></table></figure>
<p>YAML与java类型对照表：</p>
<table>
<thead>
<tr>
<th>YAML</th>
<th>JAVA</th>
</tr>
</thead>
<tbody><tr>
<td>!null</td>
<td>null</td>
</tr>
<tr>
<td>!!bool</td>
<td>Boolean</td>
</tr>
<tr>
<td>!!int</td>
<td>Integer, Long, BigInteger</td>
</tr>
<tr>
<td>!!float</td>
<td>Double</td>
</tr>
<tr>
<td>!!binary</td>
<td>String</td>
</tr>
<tr>
<td>!!timestamp</td>
<td>java.util.Date, java.sql.Date, java.sql.Timestamp</td>
</tr>
<tr>
<td>!!omap, !!pairs</td>
<td>List of Object[]</td>
</tr>
<tr>
<td>!!set</td>
<td>Set</td>
</tr>
<tr>
<td>!!str</td>
<td>String</td>
</tr>
<tr>
<td>!!seq</td>
<td>List</td>
</tr>
<tr>
<td>!!map</td>
<td>Map</td>
</tr>
</tbody></table>
<p>集合的默认实现是：</p>
<blockquote>
<ul>
<li>List:  ArrayList</li>
<li>Map:  LinkedHashMap</li>
</ul>
</blockquote>
<h3 id="使用JYaml实现"><a href="#使用JYaml实现" class="headerlink" title="使用JYaml实现"></a>使用JYaml实现</h3><p>JYaml（<strong>最新版本是2007年的，可以考虑放弃了</strong>），使用JYaml把Jone “Dump” 出来：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">File dumpfile = new File(&quot;John_dump.yaml&quot;);</span><br><span class="line">Yaml.dump(john, dumpfile);</span><br></pre></td></tr></table></figure>
<p>下面我们看看John_dump.yaml是什么样子：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">--- !yaml.test.internal.Person</span><br><span class="line">age: 37</span><br><span class="line">children: !yaml.test.internal.Person[]</span><br><span class="line">  - !yaml.test.internal.Person</span><br><span class="line">    age: 15</span><br><span class="line">    name: Jimmy Smith</span><br><span class="line">  - !yaml.test.internal.Person</span><br><span class="line">    age: 12</span><br><span class="line">    name: Jenny Smith</span><br><span class="line">name: John Smith</span><br><span class="line">sponse: !yaml.test.internal.Person</span><br><span class="line">  age: 25</span><br><span class="line">  name: Jane Smith</span><br></pre></td></tr></table></figure>
<p>其中!yaml.test.internal.Person是一些类型的信息。load的时候需要用。<br>现在用JYaml把Jone_dump.yaml load进来：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Person john2 = (Person) Yaml.loadType(dumpfile, Person.class);</span><br></pre></td></tr></table></figure>
<p>还可以用下面的代码dump出没有类型信息的John.yaml：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Yaml.dump(john,dumpfile, true);</span><br></pre></td></tr></table></figure>
<p>我们再来看看JYaml对流处理的支持，为简便起见，我们只是把同一个john写10次：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"> YamlEncoder enc = new YamlEncoder(new FileOutputStream(dumpfile));</span><br><span class="line"> for(int i=0; i&lt;10; i++)&#123;</span><br><span class="line">     john.setAge(37+i);</span><br><span class="line">     enc.writeObject(john);</span><br><span class="line">     enc.flush();</span><br><span class="line"> &#125;</span><br><span class="line">enc.close();</span><br></pre></td></tr></table></figure>
<p>下面再把这十个对象一个一个读出来（注意while循环退出的方式）：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">YamlDecoder dec = new YamlDecoder(new FileInputStream(dumpfile));</span><br><span class="line">int age = 37;</span><br><span class="line">while(true)&#123;</span><br><span class="line">    try&#123;</span><br><span class="line">        john = (Person) dec.readObject();</span><br><span class="line">        assertEquals(age, john.getAge());</span><br><span class="line">        age++;</span><br><span class="line">    &#125;catch(EOFException eofe)&#123;</span><br><span class="line">        break;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="格式"><a href="#格式" class="headerlink" title="格式"></a>格式</h3><h4 id="多行缩进"><a href="#多行缩进" class="headerlink" title="多行缩进"></a>多行缩进</h4><p>数据结构可以用类似大纲的缩排方式呈现，结构通过缩进来表示，连续的项目通过减号“-”来表示，map结构里面的key&#x2F;value对用冒号“:”来分隔。样例如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">house:</span><br><span class="line">  family:</span><br><span class="line">    name: Doe</span><br><span class="line">    parents:</span><br><span class="line">      - John</span><br><span class="line">      - Jane</span><br><span class="line">    children:</span><br><span class="line">      - Paul</span><br><span class="line">      - Mark</span><br><span class="line">      - Simone</span><br><span class="line">  address:</span><br><span class="line">    number: 34</span><br><span class="line">    street: Main Street</span><br><span class="line">    city: Nowheretown</span><br><span class="line">    zipcode: 12345</span><br></pre></td></tr></table></figure>

<h4 id="注意："><a href="#注意：" class="headerlink" title="注意："></a>注意：</h4><p>字串不一定要用双引号标识；</p>
<p>在缩排中空白字符的数目并不是非常重要，只要相同阶层的元素左侧对齐就可以了（不过不能使用TAB字符）；</p>
<p>允许在文件中加入选择性的空行，以增加可读性；</p>
<p>在一个档案中，可同时包含多个文件，并用“——”分隔；</p>
<p>选择性的符号“…”可以用来表示档案结尾（在利用串流的通讯中，这非常有用，可以在不关闭串流的情况下，发送结束讯号）。</p>
<h4 id="单行缩写"><a href="#单行缩写" class="headerlink" title="单行缩写"></a>单行缩写</h4><p>YAML也有用来描述好几行相同结构的数据的缩写语法，数组用’[]’包括起来，hash用’{}’来包括。因此，上面的这个YAML能够缩写成这样:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">house:</span><br><span class="line">  family: &#123; name: Doe, parents: [John, Jane], children: [Paul, Mark, Simone] &#125;</span><br><span class="line">  address: &#123; number: 34, street: Main Street, city: Nowheretown, zipcode: 12345 &#125;</span><br></pre></td></tr></table></figure>

        </div>

        
            <section class="post-copyright">
                
                    <p class="copyright-item">
                        <span>Author:</span>
                        <span>Tommas</span>
                    </p>
                
                
                    <p class="copyright-item">
                        <span>Permalink:</span>
                        <span><a href="https://hexo-lib.github.io/post/2017121234.htm">https://hexo-lib.github.io/post/2017121234.htm</a></span>
                    </p>
                
                
                    <p class="copyright-item">
                        <span>License:</span>
                        <span>Copyright (c) 2024 <a target="_blank" rel="noopener" href="http://creativecommons.org/licenses/by-nc/4.0/">CC-BY-NC-4.0</a> LICENSE</span>
                    </p>
                
                

            </section>
        
        <section class="post-tags">
            <div>
                <span>Tag(s):</span>
                <span class="tag">
                    
                    
                        <a href="/tags/yml/"># yml</a>
                    
                        
                </span>
            </div>
            <div>
                <a href="javascript:window.history.back();">back</a>
                <span>· </span>
                <a href="/">home</a>
            </div>
        </section>
        <section class="post-nav">
            
                <a class="prev" rel="prev" href="/post/2017121234.htm">穷忙族的人生</a>
            
            
            <a class="next" rel="next" href="/post/2017091622.htm">Markdown的语法及基本命令</a>
            
        </section>


    </article>
</div>

            </div>
            <footer id="footer" class="footer">
    <div class="copyright">
       <!--  <span>© Tommas | Powered by <a href="https://hexo.io" target="_blank">Hexo</a> & <a href="https://github.com/onxs" target="_blank">Chic</a></span>  -->
             <span>© Tommas </span>
    </div>
</footer>

    </div>
</body>

</html>